<template>
	<view class="viewfill">
		<u-navbar title="群二维码"></u-navbar>
		<view class="body">
			<canvas
				canvas-id="canvas" 
				id="canvas" 
				ref="canvas" 
				class="canvas"
				:style="{width: `${width}px`,height:`${height}px`}"
			>
			</canvas>
			<view class="btn bg-theme" @tap="save">保存到手机</view>
		</view>
	</view>
</template>

<script>
	import {delay, toast} from "@/utils/util.js"
	import QRCodeAlg from "@/utils/QS-SharePoster/QRCodeAlg.js"
	import {state} from "./bus.js"
	import {mapGetters} from "vuex"
	let base64Avatar = "";
	let bridge = null
	export default {
		data() {
			return {
				ctx: null,
				width:uni.upx2px(690),
				height:uni.upx2px(860),
				avatarInfo:{
					path:base64Avatar,
					width:100,
					height:100
				},
				userName:'',
				motto:'',
				link:'',
				tempFilePath:''
			};
		},
		computed:{
			...mapGetters('user',['userInfo']),
			info(){
				return state.info
			}
		},
		async onReady() {
			const ctx = uni.createCanvasContext('canvas', this)
			this.ctx = ctx
			this.userName = state.info.name
			this.motto = state.info.brief||'暂无群简介'
			this.link = `PATH:/pages/group/facade?id=${state.info.id}&from=${this.userInfo.userId}`
			try{
				uni.showLoading({
					title:'图片加载中'
				})
				await new Promise((resolve,reject)=>{
					uni.getImageInfo({
						src:state.info.avatar,
						success:({path,width,height})=>{
							this.avatarInfo.path = path
							this.avatarInfo.width = width
							this.avatarInfo.height = height
							resolve({path,width,height})
						},
						fail:()=>{
							reject(new Error('图片加载失败'))
						}
					})
					delay(3000).then(()=>{
						reject(new Error('图片加载超时'))
					})
				})
			}catch(e){
				console.log(e)
				
			}finally{
				uni.hideLoading()
			}
			try{
				uni.showLoading({
					title:'二维码生成中'
				})
				await this.drawCard()
				this.output()
			}catch(e){
				toast('二维码生成失败,请稍后重试')
				await delay(1000)
			}finally{
				uni.hideLoading()
			}
		},
		async onLoad() {
			
		},
		methods: {
			drawCard(){
				return new Promise((resolve,reject)=>{
					this.drawBg()
					this.drawHead()
					this.drawBody()
					this.drawfoot()
					this.ctx.draw(true,resolve),
					setTimeout(()=>{
						reject(new Error('生成超时,请重试'))
					},3000)
				})
			},
			drawRadiusRect(x,y,w,h,r){
				this.ctx.beginPath()
				this.ctx.moveTo(x,y+r)
				this.ctx.arcTo(x,y,x+r,y,r)
				this.ctx.lineTo(x+w-r,y)
				this.ctx.arcTo(x+w,y,x+w,y+r,r)
				this.ctx.lineTo(x+w,y+h-r)
				this.ctx.arcTo(x+w,y+h,x+w-r,y+h,r)
				this.ctx.lineTo(x+r,y+h)
				this.ctx.arcTo(x,y+h,x,y+h-r,r)
				this.ctx.closePath()
			},
			coverImg(bx,by,bw,bh,sw,sh){
				const multiple = Math.min(sw/bw,sh/bw)
				const width = sw/multiple;
				const height = sh/multiple;
				const x = bx - (width-bw)/2 
				const y = by - (height-bh)/2
				return {
					x,
					y,
					width,
					height
				}
			},
			txtClip(text,size,width){
				this.ctx.save()
				this.ctx.setFontSize(size)
				if(this.ctx.measureText(text).width<width){
					
				}else{
					const omit = this.ctx.measureText('...').width
					while(this.ctx.measureText(text).width+omit>width){
						text = text.slice(0,text.length-1)
					}
					text+='...'
				}
				this.ctx.restore()
				return text
			},
			drawBg(){ 
				this.ctx.save()
				this.ctx.setFillStyle("#FFFFFF")
				this.drawRadiusRect(0,0,this.width,this.height,uni.upx2px(30))
				this.ctx.fill()
				this.ctx.restore()
			},
			drawHead(){
				const avatarRect = {
					x:uni.upx2px(40),
					y:uni.upx2px(40),
					w:uni.upx2px(120),
					h:uni.upx2px(120),
					r:uni.upx2px(10)
				}
				
				this.ctx.save()
				this.ctx.setFillStyle("#F5F5F5")
				this.drawRadiusRect(avatarRect.x,avatarRect.y,avatarRect.w,avatarRect.h,avatarRect.r)
				this.ctx.fill()
				this.ctx.clip()
				const imgRect = this.coverImg(avatarRect.x,avatarRect.y,avatarRect.w,avatarRect.h,this.avatarInfo.width,this.avatarInfo.height)
				this.ctx.drawImage(this.avatarInfo.path,imgRect.x,imgRect.y,imgRect.width,imgRect.height)
				this.ctx.restore()
				
				const nameRect = {
					x:uni.upx2px(70)+avatarRect.w,
					y:uni.upx2px(50),
					w:this.width-uni.upx2px(120)-avatarRect.w,
					fontSize:uni.upx2px(32),
					color:"#333333"
				}
				const nameClip = this.txtClip(this.userName,nameRect.fontSize,nameRect.w)
				this.ctx.save()
				this.ctx.setFillStyle(nameRect.color)
				this.ctx.fillText(nameClip,nameRect.x,nameRect.y+nameRect.fontSize,nameRect.w)
				this.ctx.restore()
				
				const mottoRect = {
					x:uni.upx2px(70)+avatarRect.w,
					y:nameRect.y+nameRect.fontSize+uni.upx2px(30),
					w:nameRect.w,
					fontSize:uni.upx2px(24),
					color:"#999999"
				}
				const mottoClip = this.txtClip(this.motto,mottoRect.fontSize,mottoRect.w)
				this.ctx.save()
				this.ctx.setFillStyle(mottoRect.color)
				this.ctx.fillText(mottoClip,mottoRect.x,mottoRect.y+mottoRect.fontSize,mottoRect.w)
				this.ctx.restore()
			},
			drawBody(){
				const QRCode={
					correctLevel:3,
					color:"#333333"
				}
				const qrRect = {
					x:(this.width-uni.upx2px(560))/2,
					y:uni.upx2px(200),
					size:uni.upx2px(560),
					iconSize:uni.upx2px(120)
				}
				const qrCodeAlg = new QRCodeAlg(this.link, QRCode.correctLevel)
				const count = qrCodeAlg.getModuleCount();
				const tileSize = (qrRect.size / count).toPrecision(4)
				
				this.ctx.save()
				this.ctx.setFillStyle(QRCode.color)
				for (let row = 0; row < count; row++) {
					for (let col = 0; col < count; col++) {
						if(qrCodeAlg.modules[row][col]){
							this.ctx.fillRect(row*tileSize+qrRect.x,col*tileSize+qrRect.y,tileSize,tileSize)
						}
					}
				}
				this.ctx.restore()
				
				const iconRect={
					padding:4,
					r:4,
					x:qrRect.x+(qrRect.size-qrRect.iconSize)/2,
					y:qrRect.y+(qrRect.size-qrRect.iconSize)/2,
				}
				this.ctx.save()
				this.ctx.setFillStyle("#FFFFFF")
				this.drawRadiusRect(iconRect.x-iconRect.padding,iconRect.y-iconRect.padding,qrRect.iconSize+iconRect.padding*2,qrRect.iconSize+iconRect.padding*2,iconRect.r)
				this.ctx.fill()
				this.ctx.restore()
				
				this.ctx.save()
				this.ctx.setFillStyle("#ffffff")
				this.drawRadiusRect(iconRect.x,iconRect.y,qrRect.iconSize,qrRect.iconSize,0)
				this.ctx.fill()
				this.ctx.clip()
				const imgRect = this.coverImg(iconRect.x,iconRect.y,qrRect.iconSize,qrRect.iconSize,this.avatarInfo.width,this.avatarInfo.height)
				this.ctx.drawImage(this.avatarInfo.path,imgRect.x,imgRect.y,imgRect.width,imgRect.height)
				this.ctx.restore()
			},
			drawfoot(){
				const tip = {
					txt:'使用APP扫一扫,加我为好友',
					fontSize:uni.upx2px(24),
					color:"#999999"
				}
				this.ctx.save()
				this.ctx.setFillStyle(tip.color)
				this.ctx.setTextAlign('center')
				this.ctx.fillText(tip.txt,this.width/2,this.height-20)
				this.ctx.restore()
			},
			async output() {
				for (let i = 0; i < 3; i++) {
					try {
						const {
							tempFilePath
						} = await new Promise((resolve, reject) => {
							uni.canvasToTempFilePath({
								canvasId: 'canvas',
								success: resolve,
								// #ifdef MP
								fileType: 'jpg',
								// #endif
								fail: reject
							}, this)
						})
						this.tempFilePath = tempFilePath
						return this.tempFilePath
					} catch {
			
					}
				}
				throw new Error('导出失败')
			},
			async save(){
				try{
					uni.showLoading({
						title:"正在保存中",
						mask:true
					})
					if(!this.tempFilePath){
						await this.output()
					}
					await new Promise((resolve,reject)=>{
						uni.saveImageToPhotosAlbum({
							filePath:this.tempFilePath,
							success:resolve,
							fail:reject
						})
					})
					uni.showToast({
						title:"保存成功"
					})
				}catch(e){
					console.error(e)
					toast(e.message||'保存失败')
				}
			},
			async more(){
				const {tapIndex} = await new Promise((resolve,reject)=>{
					uni.showActionSheet({
						itemList:['保存到手机'],
						success:resolve,
						fail:reject
					})
				})
				if(tapIndex==0){
					this.save()
				}
			}
		}
	}
</script>
<style>
	page{
		background-color: #EEEEEE;
	}
</style>
<style lang="scss" scoped>
	.viewfill{
		min-height: 100vh;
		display: flex;
		flex-direction: column;
		.hide{
			position: fixed;
			top: 150vh;
			left: 150vw;
		}
	}
	.body{
		flex: 1;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		.canvas{
			background-color: #ffffff;
			border-radius: 20rpx;
		}
		.btn{
			width: 90%;
			height: 80rpx;
			margin-top: 30rpx;
			display: flex;
			justify-content: center;
			align-items: center;
			border-radius: 100rpx;
		}
	}
	.wrap{
		width: 690rpx;
		background-color: #FFFFFF;
		padding: 40rpx;
		border-radius: 30rpx;
		display: flex;
		flex-direction: column;
		.info{
			display: flex;
		}
		.avatar{
			width: 120rpx;
			height: 120rpx;
			border-radius: 10rpx;
			margin-right: 30rpx;
			flex-shrink: 0;
		}
		.data{
			display: flex;
			flex-direction: column;
			justify-content: space-around;
			flex: 1;
			width: 100rpx;
		}
		.name{
			font-size: 32rpx;
		}
		.ps{
			font-size: 24rpx;
			color: #AAAAAA;
		}
		.qrcode{
			margin-top: 50rpx;
			
			width: 560rpx;
			height: 560rpx;
			align-self: center;
			image{
				width: 100%;
				height: 100%;
			}
		}
		.tip{
			margin-top: 30rpx;
			font-size: 24rpx;
			align-self: center;
			color: #AAAAAA;
		}
	}
</style>
